package org.duang.kit;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.duang.db.sql.SqlBaseDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ThreadPoolKit {
	
	private final static Logger logger = LoggerFactory.getLogger(ThreadPoolKit.class);

	private static long KEEP_ALIVETIME = 2l;
	private static int MIN_POOL_NUMBER = 10;
	private static int MAX_POOL_NUMBER = 50;

	// 创建线程池
//	private static ExecutorService es = Executors.newFixedThreadPool(MAX_POOL_NUMBER, new NamedThreadFactory());

//	private static final ExecutorService es = new ThreadPoolExecutor(
//			MIN_POOL_NUMBER, MAX_POOL_NUMBER, KEEP_ALIVETIME, TimeUnit.HOURS, new ArrayBlockingQueue<Runnable>(MAX_POOL_NUMBER),
//            new ThreadPoolExecutor.CallerRunsPolicy());
	
	private static final ExecutorService es = new ThreadPoolExecutor(
			MIN_POOL_NUMBER, MAX_POOL_NUMBER, KEEP_ALIVETIME, TimeUnit.HOURS, new ArrayBlockingQueue<Runnable>(MAX_POOL_NUMBER),
			new NamedThreadFactory());
	
	// 执行线程
	public static void execute(Thread thread){
		try{
			es.execute(thread);
		} catch( Exception e ) {
			logger.warn("ThreadPoolKit execute is error: "+ e.getMessage(), e);
		}
	}
	
	/**
	 * 执行任务
	 * @param task
	 * @return
	 */
	public static <T> T execute(Callable<T> task) {
		try{
			FutureTask<T> futureTask = new FutureTask<>(task);
			es.submit(futureTask);
//			es.shutdown();
			return (T)futureTask.get();
		} catch (Exception e) {
			logger.warn("ThreadPoolKit execute is error: "+ e.getMessage(), e);
			return null;
		}
	}

	static class NamedThreadFactory implements ThreadFactory {
		private static final AtomicInteger pool_seq = new AtomicInteger(1);
		private final AtomicInteger mThreadNum = new AtomicInteger(1);
		private final String mPrefix;
		private final ThreadGroup mGroup;

		public NamedThreadFactory() {
			mPrefix = "duang-" + pool_seq.getAndIncrement() + "-thread-";
			SecurityManager s = System.getSecurityManager();
			mGroup = (s == null) ? Thread.currentThread().getThreadGroup() : s.getThreadGroup();
		}

		public Thread newThread(Runnable runnable) {
			String name = mPrefix + mThreadNum.getAndIncrement();
			Thread ret = new Thread(mGroup, runnable, name, 0);
			ret.setDaemon(false);
			return ret;
		}

		public ThreadGroup getThreadGroup() {
			return mGroup;
		}
	}
}
